home *** CD-ROM | disk | FTP | other *** search
/ Power Programmierung / Power-Programmierung (Tewi)(1994).iso / magazine / progjour / 1991 / 04 / netbios.pas < prev    next >
Pascal/Delphi Source File  |  1991-05-12  |  9KB  |  222 lines

  1. {*****************************************************************************
  2. ** NetBIOS Unit Version 1.2                                     May 1, 1991 **
  3. ** Copyright 1987,1988,1991 by L. Brett Glass, Systems Consultant           **
  4. ******************************************************************************}
  5.  
  6. unit NetBIOS; {Object-oriented NetBIOS interface}
  7.  
  8. {This is the latest incarnation of a unit I've used for many years (and in
  9.  many articles and programming projects) to interface to NetBIOS. The latest
  10.  version is object-oriented; NCBs are objects and can be imagined to be
  11.  performing commands on behalf if your program.}
  12.  
  13. {$R-} {$S-} {$A-}
  14.  
  15. interface
  16.  
  17. const {Codes for NetBIOS commands.
  18.        Note that only those commands for which there is a constant
  19.        ending in NO_WAIT can be executed with the no-wait option.}
  20.   {General}
  21.   ADAPTER_RESET= $32;
  22.   CANCEL = $35;
  23.   ADAPTER_STATUS = $33;
  24.   ADAPTER_STATUS_NO_WAIT = $B3;
  25.   {Remote boot support}
  26.   UNLINK = $70;
  27.   {Name support}
  28.   ADD_NAME = $30;
  29.   ADD_NAME_NO_WAIT = $B0;
  30.   ADD_GROUP_NAME = $36;
  31.   ADD_GROUP_NAME_NO_WAIT = $B6;
  32.   DELETE_NAME = $31;
  33.   DELETE_NAME_NO_WAIT = $B1;
  34.   {Session support}
  35.   CALL = $10;
  36.   CALL_NO_WAIT = $90;
  37.   LISTEN = $11;
  38.   LISTEN_NO_WAIT = $91;
  39.   HANG_UP = $12;
  40.   HANG_UP_NO_WAIT = $92;
  41.   SEND = $14;
  42.   SEND_NO_WAIT = $94;
  43.   CHAIN_SEND = $17;
  44.   CHAIN_SEND_NO_WAIT = $97;
  45.   RECEIVE = $15;
  46.   RECEIVE_NO_WAIT = $95;
  47.   RECEIVE_ANY = $16;
  48.   RECEIVE_ANY_NO_WAIT = $96;
  49.   SESSION_STATUS = $34;
  50.   SESSION_STATUS_NO_WAIT = $B4;
  51.   {Datagram support}
  52.   SEND_DATAGRAM = $20;
  53.   SEND_DATAGRAM_NO_WAIT = $A0;
  54.   SEND_BROADCAST_DATAGRAM = $22;
  55.   SEND_BROADCAST_DATAGRAM_NO_WAIT = $A2;
  56.   RECEIVE_DATAGRAM = $21;
  57.   RECEIVE_DATAGRAM_NO_WAIT = $A1;
  58.   RECEIVE_BROADCAST_DATAGRAM = $23;
  59.   RECEIVE_BROADCAST_DATAGRAM_NO_WAIT = $A3;
  60.   INTENTIONAL_BAD_COMMAND = $7F;
  61.  
  62. const {Return codes}
  63.   GOOD_RTN = $00;           {Good return}
  64.   ILL_LENGTH = $01;         {Bad length field}
  65.   INVALID_CMD = $03;        {Bad command number}
  66.   TIMEOUT = $05;            {Operation timed out}
  67.   MSG_INCOMPLETE = $06;     {Not enough space for message}
  68.   ILL_SESSION = $08;        {Session number was invalid}
  69.   NOT_AVAIL = $09;          {Adapter out of memory}
  70.   SESSION_CLOSED = $0A;     {Session closed successfully}
  71.   CMD_CANCELLED = $0B;      {Command cancelled successfully}
  72.   DUP_NAME = $0D;           {Name already in local table}
  73.   NAME_TABLE_FULL = $0E;    {Name table is full}
  74.   NAME_STILL_ACTIVE = $0F;  {Name deregistered but has active sessions}
  75.   SESSION_TABLE_FULL = $11; {No more sessions allowed}
  76.   OPEN_REJECTED = $12;      {No LISTEN pending on remote}
  77.   ILL_NAME_NUMBER = $13;    {Name number must match name}
  78.   NO_ANSWER = $14;          {Call not answered}
  79.   ILL_NAME = $15;           {Name not found or illegal}
  80.   NAME_IN_USE = $16;        {Name in use on network}
  81.   NAME_DELETED = $17;       {Name successfully deleted}
  82.   SESSION_ABEND = $18;      {Session ended abnormally}
  83.   NAME_CONFLICT = $19;      {Two names on the net are identical}
  84.   ILL_PACKET = $1A;         {Packet protocol not recognized}
  85.   BUSY = $21;               {BIOS re-entrancy error}
  86.   TOO_MANY_CMDS = $22;      {Too many commands outstanding}
  87.   INVALID_ADAPTER = $23;    {Invalid number for LAN adapter}
  88.   CMPL_DURING_CANCEL = $24; {Command completed before it could be cancelled}
  89.   CANNOT_CANCEL = $26;      {Command cannot be cancelled}
  90.   COMMAND_PENDING = $FF;    {Command is pending}
  91.  
  92. type
  93.   AdapterNum = 0..1; {Legal adapter number}
  94.   NetName = array [1..16] of Char; {Format of a name used in net operations}
  95.   {The following variant record supports the use of the
  96.    callName field of an NCB for either a network name or
  97.    buffer chaining.}
  98.   NameOrBufInfo = record
  99.     case Boolean of
  100.       FALSE: (name : NetName);       {Network name}
  101.       TRUE:  (nextBufLen : Word;     {Length of next buffer in a chain}
  102.               nextBufPtr : Pointer)  {Pointer to next buffer in a chain}
  103.       end;
  104.   NCB = object
  105.     command,          {NetBIOS command}
  106.     retcode,          {Return code}
  107.     lsn,              {Local session number}
  108.     num : Byte;       {Number of a local name}
  109.     bufPtr : Pointer; {Pointer to message buffer}
  110.     len : Word;       {Message buffer length}
  111.     callName:         {Destination name or info about second}
  112.       NameOrBufInfo;  {buffer in a CHAIN SEND)}
  113.     name : NetName;   {Source (local) name}
  114.     rto,              {Receive timeout in half seconds}
  115.     sto : Byte;       {Send timeout in half seconds}
  116.     post : Pointer;   {Interrrupt completion routine address}
  117.     lana_num : AdapterNum; {Number of LAN adapter}
  118.     cmd_cplt : Byte;  {Command complete flag}
  119.     reserved : array [1..14] of Byte; {Internal use only}
  120.     constructor Init(cmd : Byte); {Constructor}
  121.     procedure Submit; {Submit self to NetBIOS}
  122.     function ReturnCode : Byte; {Submit self. Return code is function result.}
  123.     end;
  124.  
  125. const
  126.   {Masks for jumpers field of StatusBuf record}
  127.   W1 = $40; {Mask for W1 jumper on IBM net adapter card (Remote Boot)}
  128.   W2 = $80; {Mask for W2 jumper on IBM net adapter card (Reserved)}
  129.  
  130.   NAME_STATUS_MASK = $07; {Mask for reg status of name. Apply to status field
  131.                            of a LocalName record after ADAPTER_STATUS call}
  132.   NAME_PENDING_REG = 1;   {Registration pending}
  133.   NAME_REGISTERED = 4;    {Name is registered}
  134.   NAME_DEREGISTERED = 5;  {Name now deregistered}
  135.   NAME_DUPLICATED = 6;    {Name was found to be a duplicate}
  136.   NAME_DUP_PENDING_DEREG = 7; {Duplicate name now being deregistered}
  137.  
  138.   NAME_GROUP_MASK = $80;  {Mask for group/local bit. Apply to status field
  139.                            of a LocalName record after ADAPTER_STATUS call}
  140.  
  141. type
  142.   LocalName = record
  143.     name : NetName; {The name itself}
  144.     num,            {The number of the name}
  145.     status : Byte;  {Status of name. See constants above.}
  146.     end;
  147.   StatusBuf = record
  148.     unitID : array [1..6] of Byte; {Unique ID of hardware board}
  149.     jumpers,                       {Reflects jumper settings for W1 and W2}
  150.     postResult,                    {Result byte from adapter POST}
  151.     majorVersion,                  {Software version number}
  152.     minorVersion : Byte;
  153.     period,                        {Error reporting period in minutes}
  154.     crcErrors,                     {CRC errors found}
  155.     alignErrors,                   {Alignment errors found}
  156.     collisions,                    {Collisions found}
  157.     aborts : Word;                 {Aborted transmissions}
  158.     succXmt, succRcv : Longint;    {Successful transmissions and receptions}
  159.     reXmts,                        {Retransmissions}
  160.     overruns : Word;               {Adapter buffer overruns}
  161.     reserved : array [1..8] of Byte; {For internal use}
  162.     freeNCBs,                      {How many more NCBs can there be?}
  163.     configMaxNCBs,                 {Configured max NCBs}
  164.     maxNCBs : Word;                {Actual max NCBs}
  165.     reserved2 : array [1..4] of Byte;
  166.     sessions,                      {How many sessions in progress or pending}
  167.     configMaxSessions,             {Configured max sessions}
  168.     maxSessions,                   {Actual max sessions}
  169.     maxSessionPacketSize : Word;   {Max size of packet sent during a session}
  170.     nameCount : Word;              {Number of local names}
  171.     localNames : array [1..16] of LocalName {Local name table}
  172.     end;
  173.  
  174. function NetBIOSPresent: Boolean;
  175.   {Determine if the NETBIOS (or an emulation thereof) is present}
  176.  
  177. implementation
  178.  
  179. function NCB.ReturnCode : Byte; assembler;
  180.   {Call the NetBIOS with the given NCB. The function returns the
  181.    same value that appears in the retCode field of the NCB after
  182.    the call. Note that commands issued with the no-wait option and
  183.    no interrupt completion routine will return their final result
  184.    codes in the cmd_cplt field. Note that since we can't use inline
  185.    machine code -- the most efficient solution -- in Turbo 6.0, we
  186.    use an "assembler" function here.}
  187.   asm
  188.   les  bx,self {Get the "self pointer" that's passed by all objects}
  189.   int  5Ch {Call NetBIOS}
  190.   end;
  191.  
  192. procedure NCB.Submit; assembler;
  193.   {Call the NetBIOS with the given NCB. All return codes must
  194.    be read from the NCB when using this procedure. This is also
  195.    an "assembler" function.}
  196.   asm
  197.   les  bx,self
  198.   int  5Ch
  199.   end;
  200.  
  201. constructor NCB.Init(cmd : Byte); {Constructor}
  202.   begin {InitNCB}
  203.   {Fill the NCB with zeroes, then put the command in the first
  204.    byte.}
  205.   FillChar(self,SizeOf(self),0);
  206.   command := cmd; {Add the command type}
  207.   end;  {InitNCB}
  208.  
  209. function NetBIOSPresent : Boolean;
  210.   var
  211.     netBlock : NCB;
  212.     netVec : Pointer absolute $0000:$0170;
  213.   begin {NetBIOSPresent}
  214.   NetBIOSPresent := FALSE;
  215.   if netVec = NIL then {Network can't be there if vector is all zeroes}
  216.     Exit;
  217.   netBlock.Init(INTENTIONAL_BAD_COMMAND);
  218.   {If the network's there, it will recognize a bad command}
  219.   NetBIOSPresent := (netBlock.ReturnCode = INVALID_CMD)
  220.   end;  {NetBIOSPresent}
  221. end.
  222.